#include "ET++.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "TextReader.h"

#include "Class.h"
#include "VObjectText.h"
#include "TextMarks.h"
#include "RunArray.h"
#include "String.h"

//---- TextReader --------------------------------------------------------------

NewMetaImpl0(TextReader,Object);

TextReader::TextReader(StyledText *s, CharStyle *dfltcs, ParaStyle *dfltps)
{
	st= s;
	runlen= paralen= pos= 0;
	st->Cut(0, st->End());  // clear text
	cstyles= st->GetCharStyles();
	pstyles= st->GetParaStyles();

	CharDesc cd;
	dfltcs->GetProperties(cd);
	cd.GetFontProp(font, face, size);
	ink= dfltcs->GetInk();
	dfltps->CopyProperties(paraProp);

	cstyles->Insert(dfltcs, 0, cstyles->Size(), 1);
	pstyles->Insert(dfltps, 0, cstyles->Size(), 1);

	flushed= FALSE;
}

TextReader::~TextReader()
{
	if (!flushed)
		Flush();
}

void TextReader::Flush()
{
	if (runlen > 0)
		FlushCharProp();
	if (paralen > 0) {
		int end= pstyles->Size()-1; // terminator!
		pstyles->Insert(new_ParaStyle(paraProp), end, end+1, paralen+1);
	}
	flushed= TRUE;
}

void TextReader::Append(byte b)
{
	if (b != 0) {
		st->AddChar(pos, b);
		runlen++;
		paralen++;
		pos++;
		if (Text::IsPara(b))
			FlushParaProp();
	}
}

void TextReader::Append(const char *s, int len)
{
	if (s == 0)
		return;
	if (len < 0)
		len= strlen(s);
	for (int i= 0; i < len; i++)
		Append((byte) s[i]);
}

void TextReader::FlushCharProp()
{
	int end= cstyles->Size()-1;
	cstyles->Insert(new_CharStyle(font, face, size, ink), end, end, runlen);
	runlen= 0;
}

void TextReader::FlushParaProp()
{
	int end= pstyles->Size()-1;
	pstyles->Insert(new_ParaStyle(paraProp), end, end, paralen);
	paralen= 0;
}

void TextReader::SetParaProp(TxtParaProp what, int value)
{
	paraProp.SetProperty(what, value);
}

void TextReader::SetParaProp(ParaDesc &pd)
{
	paraProp= pd;
}

void TextReader::InsertVObject(VObject *vop)
{
	if (!st->IsKindOf(VObjectText))
		return;
	InsertVisualMark(new VObjectMark(vop));
}

void TextReader::InsertVisualMark(VisualMark *gip)
{
	if (!st->IsKindOf(VObjectText))
		return;
	VObjectText *vt= (VObjectText*)st;

	gip->CalcExtent();
	gip->ChangeMark(pos, 1);
	vt->GetVisualMarks()->Add(gip);
	Append(cMarkChar);
}

void TextReader::SetFont(GrFont f)
{
	if (f == font)
		return;
	if (runlen > 0)
		FlushCharProp();
	font= f;
}

void TextReader::SetSize(int s)
{
	if (s == size)
		return;
	if (runlen > 0)
		FlushCharProp();
	size= s;
}

void TextReader::SetInk(Ink *i)
{
	if (i == ink)
		return;
	if (runlen > 0)
		FlushCharProp();
	ink= i;
}

void TextReader::SetFace(GrFace fc, int b)
{
	SetFace((GrFace) (b ? face | fc : face & ~fc));
}

void TextReader::ToggleFace(GrFace fc)
{
	SetFace((GrFace) (face ^ fc));
}

void TextReader::SetFace(GrFace fc)
{
	if (fc == face)
		return;
	if (runlen > 0)
		FlushCharProp();
	face= fc;
}

